const log4js = require('../../../utils/logUtils');
const logger = log4js.getLogger('sip');
const sip = require("sip");
const digest = require("sip/digest");
const fxp = require("fast-xml-parser");
const aliveHandler = require("./aliveHandler");
const sipUtils = require("../../../utils/sipUtils");
const config = require("../../../db/config");
const clientUtils = require("./clientUtils");
const register28181 = require("../../../schedules/register28181");

const TAG = "[向上级连] [国标注册]";
module.exports={
    /**
     * 处理设备的 register 消息
     */
    async handle(deviceid, rq) {


    },
    /**
     * register第一步
     * @param cseq
     * @param success 注册成功后的回调
     */
    async REGISTER_ONCE(cseq, success) {
        const that = this;
        const { upwardUri, upward, selfUri } = await clientUtils.generateClientParams();

        const method = 'REGISTER';
        sip.send({
            method: method, uri: upwardUri, version: config.sip.version,
            content: '', transport: 'udp',
            headers: {
                from: {uri: selfUri, params: {tag: sipUtils.rstring()}},
                to: {uri: upwardUri},
                'call-id': sipUtils.rstring(),
                cseq: {method: method, seq: 1},
                contact: '<sip:' + upward.self_account + '@' + config.localIp + ':' + upward.self_port + '>',
                'expires': '3600',
                'content-length': 0,
                'Max-Forwards': 70
            }
        }, function (rs) {
            if (rs.status === 401) {
                that.Authorization( rs, method, success);
            } else if (rs.status === 408) {
                //注册失败
                logger.warn(TAG, '注册失败', upwardUri);
            } else if (rs.status >= 300) {
                logger.info(TAG, 'call failed with status ' + rs.status);
            } else if (rs.status < 200) {
                logger.info(TAG, 'call progress status ' + rs.status);
            } else {
                logger.info(TAG, 'authorization error');
            }
        });
    },
    /**
     * 注册的第2步，客户端签名
     * @param {*} rs
     * @param {*} method
     * @param {*} success
     */
    async Authorization( rs, method, success) {
        const { upwardUri, upward, selfUri } = await clientUtils.generateClientParams();
        const session = {realm: upward.upper_realm};
        logger.info(TAG, "向上级连 sip server uri:", upwardUri,'selfUri=', selfUri);
        const req = {
            method,
            uri: upwardUri,
            headers: {
                to: {uri: upwardUri},
                from: {uri: selfUri, params: {tag: sipUtils.rstring()}},
                'call-id': sipUtils.rstring(),
                cseq: rs.headers.cseq,
                contact: '<sip:' + upward.self_account + '@' + config.localIp + ':' + upward.self_port + '>',
                'expires': '3600',
                'content-length': 0,
                'Max-Forwards': 70
            }
        };
        const auth = rs.headers['www-authenticate'];

        digest.signRequest(session, req, rs, auth);
        const ha1 = digest.calculateHA1({
            'user': upward.self_account,
            'realm': upward.upper_realm,
            'password': upward.upper_password,
            'algorithm': 'MD5'
        });
        const authorization = req.headers.authorization[0];
        let response = digest.calculateDigest({
                'ha1': ha1,
                nonce: auth[0].nonce.replace(/"/g, ''),
                nc: authorization.nc,
                cnonce: authorization.cnonce.replace(/"/g, ''),
                qop: authorization.qop,
                method: method,
                uri: authorization.uri.replace(/"/g, '')
            }
        );
        req.headers.authorization[0].response = '"' + response + '"';
        req.headers.authorization[0].username = '"' + upward.self_account + '"';
        sip.send(req, function (rs) {
            if (rs.status === 401) {
                logger.error(TAG, 'register 第二步失败');
                // 重新注册
                setTimeout(function () {
                    register28181.start();
                }, 1000*20);
            } else {
                success(rs);
                const content = fxp.parse(rs.content);
                aliveHandler.INTERVAL_CHANNEL(content);
            }
        });
    },
}
